package com.liujit.common.domain.result;

import cn.hutool.core.util.StrUtil;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonPropertyOrder;
import com.liujit.common.enums.BusinessExceptionEnum;
import com.liujit.common.enums.ResultCode;
import com.liujit.common.exception.BusinessException;
import com.liujit.common.utils.ReqUtil;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.http.HttpStatus;

import java.io.Serializable;
import java.util.Date;

/**
 * @Description: 接口错误返回结果
 * @Author: liujun
 * @Date: 2021/7/1 1:42 下午
 */
@Builder
@AllArgsConstructor
@NoArgsConstructor
@Data
@JsonPropertyOrder({ "status", "error", "path", "timestamp", "exception", "code", "msg", "errors" })
@JsonInclude(JsonInclude.Include.NON_EMPTY)
@ApiModel(value = "ErrorResult", description = "接口错误返回结果")
public class ErrorResult implements Serializable {

    private static final long serialVersionUID = 1899083570489722793L;

    /**
     * HTTP响应状态码 {@link HttpStatus}
     */
    @ApiModelProperty(value = "HTTP响应状态码")
    private Integer status;

    @ApiModelProperty(value = "HTTP响应状态码的英文提示")
    private String error;

    @ApiModelProperty(value = "调用接口路径")
    private String path;

    @ApiModelProperty(value = "时间戳")
    private Date timestamp;

    @ApiModelProperty(value = "异常的名字")
    private String exception;

    @ApiModelProperty(value = "异常返回code")
    private Integer code;

    @ApiModelProperty(value = "异常返回信息")
    private String msg;

    @ApiModelProperty(value = "异常的错误传递的数据")
    private Object errors;

    public static ErrorResult failure(ResultCode resultCode, Throwable e, HttpStatus httpStatus, Object errors) {
        ErrorResult result = ErrorResult.failure(resultCode, e, httpStatus);
        result.setErrors(errors);
        return result;
    }

    public static ErrorResult failure(ResultCode resultCode, Throwable e, HttpStatus httpStatus) {
        ErrorResult result = new ErrorResult();
        result.setCode(resultCode.code());
        result.setMsg(resultCode.msg());
        result.setStatus(httpStatus.value());
        result.setError(httpStatus.getReasonPhrase());
        result.setException(e.getClass().getName());
        String path = ReqUtil.getRequest().getRequestURI();
        result.setPath(path);
        result.setTimestamp(new Date());
        return result;
    }

    public static ErrorResult failure(BusinessException e) {
        BusinessExceptionEnum ee = BusinessExceptionEnum.getByEClass(e.getClass());
        if (ee != null) {
            return ErrorResult.failure(ee.getResultCode(), e, ee.getHttpStatus(), e.getErrors());
        }
        ErrorResult result = ErrorResult
                .failure(e.getResultCode() == null ? ResultCode.SUCCESS : e.getResultCode(), e, HttpStatus.OK,
                        e.getErrors());
        if (StrUtil.isNotEmpty(e.getMsg())) {
            result.setMsg(e.getMsg());
        }
        return result;
    }
}
